package main;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JRadioButton;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;


public class NewScoreScreen extends JDialog implements ActionListener, WindowListener{

	private final String[] POSSIBLE_ONE_BEAT = {"2","4","8", "16", "32"};
	private final Dimension SIZE = new Dimension(500,500);

	private QNote parent;
	private JLabel namePane = new JLabel("  Composition Name:");
	private JLabel keyPane = new JLabel("  Key Signature:");
	private JLabel timePane = new JLabel("  Time Signature");
	private JTextField nameInput = new JTextField(20);
	private JComboBox keyChooser = new JComboBox(KeySignature.MAJOR_KEY_INDEX);
	private JComboBox modalChooser = new JComboBox(new String[]{"Major", "Minor"});
	private JLabel keyLabel = new JLabel();
	private JComboBox oneBeat = new JComboBox(POSSIBLE_ONE_BEAT);
	private SpinnerNumberModel model = new SpinnerNumberModel(4,1,100,1);
	private JSpinner bpm = new JSpinner(model);
	private String name;
	private String key;
	private TimeSignature time;
	private boolean major = true;
	private JRadioButton trebleButton = new JRadioButton("Treble");
	private JRadioButton bassButton = new JRadioButton("Bass");
	private ButtonGroup clefButtons = new ButtonGroup();
	private GridBagLayout layout = new GridBagLayout();
	private JButton go = new JButton("Create");
	private GridBagConstraints c = new GridBagConstraints();


	/**
	 * Generates a new score dialog
	 * @param p Parent component
	 */
	public NewScoreScreen(QNote p){
		super(p, "New Score", true);
		parent = p;
		setLayout(layout);
		setResizable(false);

		clefButtons.add(trebleButton);
		clefButtons.add(bassButton);
		trebleButton.setSelected(true);

		keyChooser.setSelectedIndex(0);
		keyLabel.setText(makeKeyLabel());
		modalChooser.setSelectedIndex(0);

		//Shows the amount of accidentals when you change key
		final ActionListener keyChooseListener  = new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				GridBagConstraints c = layout.getConstraints(keyLabel);
				remove(keyLabel);
				keyLabel.setText(makeKeyLabel());
				add(keyLabel, c);
				keyLabel.revalidate();
				update(getGraphics());
			}
		};

		keyChooser.addActionListener(keyChooseListener);

		//Changes the text and list when you change between major and minor
		modalChooser.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent arg0) {
				GridBagConstraints c = layout.getConstraints(keyChooser);
				GridBagConstraints c2 = layout.getConstraints(keyLabel);
				remove(keyChooser);
				remove(keyLabel);
				if(modalChooser.getSelectedIndex() == 0){
					major = true;
					keyChooser = new JComboBox(KeySignature.MAJOR_KEY_INDEX);
				}else{
					major = false;
					keyChooser = new JComboBox(KeySignature.MINOR_KEY_INDEX);
				}
				keyChooser.addActionListener(keyChooseListener);
				keyChooser.setSelectedIndex(0);
				keyLabel.setText(makeKeyLabel());
				add(keyChooser,c);
				add(keyLabel, c2);
				keyLabel.revalidate();
				keyChooser.revalidate();
				update(getGraphics());
			}
		});

		go.addActionListener(this);
		oneBeat.setSelectedIndex(1);


		//Formating using GridBagLayout
		c.gridx = 0; c.gridy=0; c.gridheight = 1; c.gridwidth = 1; c.anchor = GridBagConstraints.LINE_START; c.ipady = 5;
		add(namePane, c);
		c.gridx = 1; c.gridy=0; c.gridheight = 1; c.gridwidth = 3; c.anchor = GridBagConstraints.CENTER;
		add(nameInput, c);


		c.gridx = 0; c.gridy=1; c.gridheight = 1; c.gridwidth = 1; c.anchor = GridBagConstraints.LINE_START; c.ipady = 5;
		add(keyPane, c);
		c.gridx = 1; c.gridy=1; c.gridheight = 1; c.gridwidth = 1; c.anchor = GridBagConstraints.CENTER;
		add(keyChooser,c);
		c.gridx = 2; c.gridy=1; c.gridheight = 1; c.gridwidth = 1;
		add(modalChooser,c);
		c.gridx = 3; c.gridy=1; c.gridheight = 1; c.gridwidth = 1; c.anchor = GridBagConstraints.LINE_END;
		add(keyLabel,c);


		c.gridx = 0; c.gridy=2; c.gridheight = 2; c.gridwidth = 1; c.anchor = GridBagConstraints.LINE_START; c.ipady = 5;
		add(timePane,c);
		c.gridx = 2; c.gridy=2; c.gridheight = 1; c.gridwidth = 1; c.anchor = GridBagConstraints.CENTER; c.ipady = 1;
		add(bpm,c);
		c.gridx = 2; c.gridy=3; c.gridheight = 1; c.gridwidth = 1;
		add(oneBeat,c);


		c.gridx = 0; c.gridy = 4; c.gridheight = 1; c.gridwidth = 2; c.anchor = GridBagConstraints.LINE_START; c.ipady = 5;
		add(new JLabel("  Clef: "), c);
		c.gridx = 2; c.gridwidth = 1; c.anchor = GridBagConstraints.CENTER;
		add(trebleButton, c);
		c.gridx = 3;
		add(bassButton, c);

		c.gridx = 0; c.gridy = 5; c.gridwidth = 4;
		add(go, c);

		pack();
		getRootPane().setDefaultButton(go);
		int xLoc = (parent.getWidth()-getWidth())/2;
		int yLoc = (parent.getHeight()-getHeight())/2;
		setLocation(xLoc,yLoc);
		setLocationRelativeTo(parent);
		setVisible(true);
	}

	/**
	 * Generates the the string for the key lable
	 * @return "Key has x sharps/flats" or "Key has no accidentals"
	 */
	private String makeKeyLabel() {
		String s = (String) keyChooser.getSelectedItem();
		int keyCode = 0;
		String[] keyList = major?KeySignature.MAJOR_KEY_INDEX:KeySignature.MINOR_KEY_INDEX;
		for(int i = 0; i < keyList.length; i++)
			if(s.equals(keyList[i])){
				keyCode = KeySignature.SHARPS_FLATS[i];
				break;
			}
		boolean sharps = (keyCode >= 0);
		keyCode = Math.abs(keyCode);
		String str =  "Key has " + keyCode;
		if(sharps)
			if(keyCode > 0){
				str += " sharp";
			}else str += " accidentals";
		else str += " flat";
		if (keyCode > 1) str += "s";
		int diff = "Key has 0 accidentals".length()-str.length();
		return str;	
	}

	@Override
	public void windowActivated(WindowEvent arg0) {}

	@Override
	public void windowClosed(WindowEvent arg0) {}

	@Override
	public void windowClosing(WindowEvent arg0) {
		System.exit(0);	
	}

	@Override
	public void windowDeactivated(WindowEvent arg0) {}

	@Override
	public void windowDeiconified(WindowEvent arg0) {}

	@Override
	public void windowIconified(WindowEvent arg0) {}

	@Override
	public void windowOpened(WindowEvent arg0) {}

	/**
	 * Sends all the information to the parent in order to create a new score
	 */
	public void actionPerformed(ActionEvent e) {
		key = (String)keyChooser.getSelectedItem();
		boolean maj = major;
		name = nameInput.getText();
		int beats = (Integer) bpm.getValue();
		int ob = Integer.parseInt((String)oneBeat.getSelectedItem());
		time = new TimeSignature(beats, ob);
		String clef;
		if(trebleButton.isSelected()) clef = "treble";
		else clef = "bass";

		parent.newScore(name, SIZE, clef, key, maj, time);
		dispose();
	}


}

